package api

import (
	"day5/user-sage/auth-service/basic/inits"
	"day5/user-sage/auth-service/basic/pkg"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

func SendSms(c *gin.Context) {
	tel := c.Query("tel")
	if tel == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 0,
			"msg":  "手机号不能为空",
		})
		return // 注意这里漏了return，会导致继续执行后续代码
	}

	// 1. 用手机号作为键的一部分，实现按手机号限制
	countKey := "sms:count:" + tel
	expireKey := "sms:expire:" + tel // 用于控制5分钟窗口

	// 2. 获取计数，兼容键不存在的情况（首次请求）
	result, err := inits.Rdb.Get(inits.Ctx, countKey).Result()
	if err != nil && err.Error() != "redis: nil" {
		// 只有Redis操作真正出错时才返回系统错误
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 0,
			"msg":  "系统错误",
		})
		return
	}

	// 3. 处理计数（键不存在时默认0）
	count := 0
	if result != "" {
		count, err = strconv.Atoi(result)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"code": 0,
				"msg":  "转化失败",
			})
			return
		}
	}

	// 4. 检查是否超过5分钟3次限制
	if count >= 3 {
		ttl, err := inits.Rdb.TTL(inits.Ctx, expireKey).Result()
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"code": 0,
				"msg":  "短信发送过于频繁",
			})
			return
		}
		c.JSON(http.StatusTooManyRequests, gin.H{
			"code": 0,
			"msg":  "5分钟内最多发送3条，请" + strconv.FormatInt(int64(ttl.Seconds()), 10) + "秒后再试",
		})
		return
	}

	// 5. 生成验证码并发送
	code := rand.Intn(9000) + 1000
	_, err = pkg.SendSms(tel, strconv.Itoa(code))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 0,
			"msg":  "发送失败: " + err.Error(),
		})
		return
	}

	// 6. 更新计数和过期时间
	if count == 0 {
		// 首次发送：初始化计数为1，设置5分钟过期
		inits.Rdb.Set(inits.Ctx, countKey, "1", 5*time.Minute)
		inits.Rdb.Set(inits.Ctx, expireKey, "1", 5*time.Minute)
	} else {
		// 非首次：计数自增
		inits.Rdb.Incr(inits.Ctx, countKey)
	}

	// 7. 存储验证码（按手机号区分，避免冲突）
	inits.Rdb.Set(inits.Ctx, "sms:code:"+tel, code, 3*time.Hour)

	// 8. 返回成功响应
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "发送成功",
		"data": code,
	})
}
